package uk.ac.durham.tel.synergynet.covanto.workspace.ui.model;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.resource.ImageDescriptor;

import uk.ac.durham.tel.commons.collections.CollectionChangeEvent;
import uk.ac.durham.tel.commons.collections.CollectionChangeListener;
import uk.ac.durham.tel.commons.collections.CollectionDiffEntry;

import uk.ac.durham.tel.commons.jface.node.AbstractBaseParent;
import uk.ac.durham.tel.commons.jface.node.DisposeException;
import uk.ac.durham.tel.commons.jface.node.INode;
import uk.ac.durham.tel.commons.jface.node.NodeRemoveException;

import uk.ac.durham.tel.synergynet.covanto.LogUtil;
import uk.ac.durham.tel.synergynet.covanto.LogUtil.LogStatus;

import uk.ac.durham.tel.synergynet.covanto.project.model.ProjectInfo;
import uk.ac.durham.tel.synergynet.covanto.project.ui.model.ProjectNode;

import uk.ac.durham.tel.synergynet.covanto.workspace.WorkspaceController;

public class WorkspaceNode extends AbstractBaseParent<Object> {
	
	private Map<ProjectInfo, ProjectNode> childrenNodesMap = new HashMap<ProjectInfo, ProjectNode>(); 
	
	public WorkspaceNode(Object resourceValue) {
		super(resourceValue, null);
		loadProjectInfoList();
		addProjectInfoListChangeListener();
	}
	
	private CollectionChangeListener projectInfoListChangeListener = new CollectionChangeListener() {
		@Override
		public void listChanged(CollectionChangeEvent event) {
			for (CollectionDiffEntry<?> diffEntry : event.getListDiff().getDifferences()) {
				if (diffEntry.isAddition())
					addProjectNode((ProjectInfo) diffEntry.getElement());
				else removeProjectNode((ProjectInfo) diffEntry.getElement());
			}
		}
	};

	
	private void loadProjectInfoList() {
		for (ProjectInfo projectInfo : WorkspaceController.getInstance().getWorkspaceRoot().getProjectInfoList()) {
			addProjectNode(projectInfo);
		}
	}

	private void addProjectInfoListChangeListener() {
		WorkspaceController.getInstance().getWorkspaceRoot().addProjectListChangeListener(projectInfoListChangeListener);
	}

	
	private void removeProjectNode(ProjectInfo projectInfo) {
		try {
			this.deleteChildren(new INode[] {childrenNodesMap.get(projectInfo)});
		} catch (NodeRemoveException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to remove Project node", e);
		}
	}

	private void addProjectNode(ProjectInfo projectInfo) {
		ProjectNode projectNode = new ProjectNode(projectInfo, this);
		childrenNodesMap.put(projectInfo, projectNode);
		this.addChildren(projectNode);
	}
	
	private void removeProjectInfoListChangeListener() {
		WorkspaceController.getInstance().getWorkspaceRoot().removeProjectListChangeListener(projectInfoListChangeListener);
	}

	@Override
	public String getLabel() {
		return "Root Workspace";
	}

	@Override
	public List<String> getChildrenNames() {
		return null;
	}

	@Override
	public void dispose() throws DisposeException {
		removeProjectInfoListChangeListener();
		try {
			clearChildren();
		} catch (NodeRemoveException e) {
			LogUtil.log(LogStatus.ERROR, "Unable to dispose children", e);
		}
	}


	@Override
	public ImageDescriptor getIcon() {
		// TODO Auto-generated method stub
		return null;
	}

}
